package thinkingInJava.typeinfo;
//: typeinfo/pets/Individual.java

import static thinkingInJava.YTool.YPrint.println;

import java.util.Iterator;
import java.util.Set;

import thinkingInJava.containers.SimpleHashSet;

public class Individual implements Comparable<Individual> {
private static long counter = 0;
private final long id = counter++;
private String name;	// 由于 hashCode 有用到这个值，所以它不能改
//final private String name;	// 由于 hashCode 有用到这个值，所以它不能改
public Individual(String name) { this.name = name; }
// 由于 name 用来计算 hashCode, 因此 name 绝对不能被改变，否则放入容器中时  hashCode 会变化导致 get 到错误的值
//public void SetName(String n){ this.name = n;}
// 'name' is optional:
public Individual() {}
public String toString() {
  return getClass().getSimpleName() +
    (name == null ? "" : " " + name);
}
public long id() { return id; }
public boolean equals(Object o) {
  return o instanceof Individual &&
    id == ((Individual)o).id;
}
public int hashCode() {
  int result = 17;
//  if(name != null)
//    result = 37 * result + name.hashCode();
  result = 37 * result + (int)id;
  return result;
}
public int compareTo(Individual arg) {
  // Compare by class name first:
  String first = getClass().getSimpleName();
  String argFirst = arg.getClass().getSimpleName();
  int firstCompare = first.compareTo(argFirst);
  if(firstCompare != 0)
  return firstCompare;
  if(name != null && arg.name != null) {
    int secondCompare = name.compareTo(arg.name);
    if(secondCompare != 0)
      return secondCompare;
  }
  return (arg.id < id ? -1 : (arg.id == id ? 0 : 1));
}

static public void main(){
	Set<Individual> m = new SimpleHashSet<Individual>();
	//Set<Individual> m = new HashSet<Individual>();
	m.add(new Individual("a"));
	m.add(new Individual("b"));
	m.add(new Individual("c"));
	println(m);
	Iterator<Individual> it = m.iterator();
	Individual iv = it.next();
	//iv.SetName("aa");	如果可以改就下面就错了，因为 hashCode 被改了
	println(m.contains(iv));
}
} ///:~
